package com.mdr.imedera.util.wx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mdr.imedera.exception.wx.AccessTokenException;
import com.mdr.imedera.util.ApplicationContextUtil;
import com.mdr.imedera.util.RedisUtil;
import com.mdr.imedera.util.request.RequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * @Author wxb
 * @Datatime 2020/10/19 16:16
 * @Descript access_token 是公众号的全局唯一接口调用凭证。公众号调用接口都需要调用access_token.
 *   🖤：1.access_token 的存储至少需要保留512个字符空间。
 *      2.有效时间目前为两个小时，需定时刷新。
 *      3.重复获取将导致上次获取的access_token 失效。
 */
@Slf4j
@Component
public class AccessToken {

    @Resource
    private RedisUtil redisUtil;

    private static  String getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?";

    /**
     * 创建 带access_token的map集合
     * @return map集合
     */
    public Map<String,String> createParamsMap(){
        Map<String,String> map = new HashMap<>();
        map.put("access_token", getAccessToken());
        return map;
    }

    /**
     * 将accesstoken追加到请求地址末尾
     * @param url 接口地址
     * @return
     */
    public String setAccessTokenAddToUrl(String url){
        return url +"access_token=" +getAccessToken();
    }

    /**
     * 获取AccessToken，并将AccessToken保存到Redis中进行保存
     * @return accessToken 字符串
     *  步骤：1.从Redis中获取access_token
     *         2.存在则直接返回，不存在则需要重新获取并返回
     */
    public  String getAccessToken(){
        //从Redis中获取access_token的值
        String access_token = (String) redisUtil.get("access_token");
        if(null==access_token){
            //1.获取请求的参数
            Map<String,String> params = new LinkedHashMap<>();
            params.put("grant_type","client_credential");
            params.put("appid", ApplicationContextUtil.getProperty("system.wx.appid"));
            params.put("secret",ApplicationContextUtil.getProperty("system.wx.secret"));
            //获取请求accesssToken的结果
            String requestResult = RequestUtils.getRequest(getAccessTokenUrl, params);
            log.info("GET ACCESS_TOKEN：{}",requestResult);
            //解析获取到的accessToken的结果(依靠fastjson将获取的字符串转换为JSON对象)
            JSONObject getATObj = JSON.parseObject(requestResult);
            //判断当前获取access_token是否正确.如果获取到错误，则抛出异常
            if(getATObj.getString("errcode")!=null){
                throw new AccessTokenException(getATObj.getString("errcode"));
            }
            //如果判断正确，则将获取到的正确的accessToken 保存到Redis中
            boolean set = redisUtil.set("access_token", getATObj.getString("access_token"), Integer.parseInt(getATObj.getString("expires_in")));
            //判断当前插入
            if(!set){
                log.info("Reids 保存 access_token 失败");
            }
            access_token = getATObj.getString("access_token");
        }
        return access_token;
    }







}
